home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / CPASCII.C < prev    next >
C/C++ Source or Header  |  1993-07-06  |  10KB  |  445 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    cpascii.c
  5. //   Title:    Compress Library
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains code to do a simple ascii compression technique. 8 bit
  25. //    ASCII codes are converted into packed 6 bit codes.
  26. //
  27. //    All lower case characters are converted to upper case.
  28. //    The following characters are ignored:
  29. //        ASCII 1..31    (Control characters)
  30. //        Underscore 
  31. //        Tilde 
  32. //        Caret 
  33. //        Bar |
  34. //        Back quote `
  35. //        Del (127)
  36. //        Backslash
  37. //
  38. //    One advantage of this method is that ASCII sort order is preserved in the
  39. //    encoded string.
  40. //
  41. //    The code in this module should be written entirely in C. 
  42. //    Do not use any C++ constructs.
  43. //
  44. //    This module is portable to:
  45. //        DOS 3.X+
  46. //        MS Windows 3.X+
  47. //        OS/2 2.X+
  48. //        OS/2 2.0 PM
  49. //        SCO UNIX.
  50. //
  51. //    The following compilers are supported:
  52. //        MSC 6.0A
  53. //        MSC/C++ 7.0
  54. //        Borland C++ 3.1 for DOS
  55. //        Borland C++ 1.0 for OS/2 2.X
  56. //        SCO UNIX cc
  57. //
  58. //----------------------------------------------------------------------------
  59. #include <cp.h>
  60.  
  61.  
  62. //----------------------------------------------------------------------------
  63. //    Data
  64. //----------------------------------------------------------------------------
  65. static BYTE bAscii2Encoded[128] =
  66.     {
  67.     0,         /* 0   ' ' */
  68.     255,        /* 1   ' ' */
  69.     255,        /* 2   ' ' */
  70.     255,        /* 3   ' ' */
  71.     255,        /* 4   ' ' */
  72.     255,        /* 5   ' ' */
  73.     255,        /* 6   ' ' */
  74.     255,        /* 7   ' ' */
  75.     255,        /* 8   ' ' */
  76.     255,        /* 9   ' ' */
  77.     255,        /* 10  ' ' */
  78.     255,        /* 11  ' ' */
  79.     255,        /* 12  ' ' */
  80.     255,        /* 13  ' ' */
  81.     255,        /* 14  ' ' */
  82.     255,        /* 15  ' ' */
  83.     255,        /* 16  ' ' */
  84.     255,        /* 17  ' ' */
  85.     255,        /* 18  ' ' */
  86.     255,        /* 19  ' ' */
  87.     255,        /* 20  ' ' */
  88.     255,        /* 21  ' ' */
  89.     255,        /* 22  ' ' */
  90.     255,        /* 23  ' ' */
  91.     255,        /* 24  ' ' */
  92.     255,        /* 25  ' ' */
  93.     255,        /* 26  ' ' */
  94.     255,        /* 27  ' ' */
  95.     255,        /* 28  ' ' */
  96.     255,        /* 29  ' ' */
  97.     255,        /* 30  ' ' */
  98.     255,        /* 31  ' ' */
  99.     1,            /* 32  ' ' */
  100.     2,           /* 33  '!' */
  101.     3,           /* 34  '"' */
  102.     4,           /* 35  '#' */
  103.     5,           /* 36  '$' */
  104.     6,           /* 37  '%' */
  105.     7,           /* 38  '&' */
  106.     8,           /* 39  ''' */
  107.     9,           /* 40  '(' */
  108.     10,       /* 41  ')' */
  109.     11,        /* 42  '*' */
  110.     12,        /* 43  '+' */
  111.     13,        /* 44  ',' */
  112.     14,        /* 45  '-' */
  113.     15,        /* 46  '.' */
  114.     16,        /* 47  '/' */
  115.     17,        /* 48  '0' */
  116.     18,        /* 49  '1' */
  117.     19,        /* 50  '2' */
  118.     20,        /* 51  '3' */
  119.     21,        /* 52  '4' */
  120.     22,        /* 53  '5' */
  121.     23,        /* 54  '6' */
  122.     24,        /* 55  '7' */
  123.     25,        /* 56  '8' */
  124.     26,        /* 57  '9' */
  125.     27,        /* 58  ':' */
  126.     28,        /* 59  ';' */
  127.     29,        /* 60  '<' */
  128.     30,        /* 61  '=' */
  129.     31,        /* 62  '>' */
  130.     32,        /* 63  '?' */
  131.     33,        /* 64  '@' */
  132.     34,        /* 65  'A' */
  133.     35,        /* 66  'B' */
  134.     36,        /* 67  'C' */
  135.     37,        /* 68  'D' */
  136.     38,        /* 69  'E' */
  137.     39,        /* 70  'F' */
  138.     40,        /* 71  'G' */
  139.     41,        /* 72  'H' */
  140.     42,        /* 73  'I' */
  141.     43,        /* 74  'J' */
  142.     44,        /* 75  'K' */
  143.     45,        /* 76  'L' */
  144.     46,        /* 77  'M' */
  145.     47,        /* 78  'N' */
  146.     48,        /* 79  'O' */
  147.     49,        /* 80  'P' */
  148.     50,        /* 81  'Q' */
  149.     51,        /* 82  'R' */
  150.     52,        /* 83  'S' */
  151.     53,        /* 84  'T' */
  152.     54,        /* 85  'U' */
  153.     55,        /* 86  'V' */
  154.     56,        /* 87  'W' */
  155.     57,        /* 88  'X' */
  156.     58,        /* 89  'Y' */
  157.     59,        /* 90  'Z' */
  158.     60,        /* 91  '[' */
  159.     255,        /* 92  '\' */
  160.     61,        /* 93  ']' */
  161.     255,        /* 94  '^' */
  162.     255,        /* 95  '_' */
  163.     255,        /* 96  '`' */
  164.     34,        /* 97  'a' */
  165.     35,        /* 98  'b' */
  166.     36,        /* 99  'c' */
  167.     37,        /* 100 'd' */
  168.     38,        /* 101 'e' */
  169.     39,        /* 102 'f' */
  170.     40,        /* 103 'g' */
  171.     41,        /* 104 'h' */
  172.     42,        /* 105 'i' */
  173.     43,        /* 106 'j' */
  174.     44,        /* 107 'k' */
  175.     45,        /* 108 'l' */
  176.     46,        /* 109 'm' */
  177.     47,        /* 110 'n' */
  178.     48,        /* 111 'o' */
  179.     49,        /* 112 'p' */
  180.     50,        /* 113 'q' */
  181.     51,        /* 114 'r' */
  182.     52,        /* 115 's' */
  183.     53,        /* 116 't' */
  184.     54,        /* 117 'u' */
  185.     55,        /* 118 'v' */
  186.     56,        /* 119 'w' */
  187.     57,        /* 120 'x' */
  188.     58,        /* 121 'y' */
  189.     59,        /* 122 'z' */
  190.     62,        /* 123 '{' */
  191.     255,        /* 124 '|' */
  192.     63,        /* 125 '}' */
  193.     255,        /* 126 '~' */
  194.     255,        /* 127 ' ' */
  195.     };
  196.  
  197. static BYTE bEncoded2Ascii[64] =
  198.     {
  199.     '\0',
  200.     ' ',
  201.     '!',
  202.     '"',
  203.     '#',
  204.     '$',
  205.     '%',
  206.     '&',
  207.     '\'',
  208.     '(',
  209.     ')',
  210.     '*',
  211.     '+',
  212.     ',',
  213.     '-',
  214.     '.',
  215.     '/',
  216.     '0',
  217.     '1',
  218.     '2',
  219.     '3',
  220.     '4',
  221.     '5',
  222.     '6',
  223.     '7',
  224.     '8',
  225.     '9',
  226.     ':',
  227.     ';',
  228.     '<',
  229.     '=',
  230.     '>',
  231.     '?',
  232.     '@',
  233.     'A',
  234.     'B',
  235.     'C',
  236.     'D',
  237.     'E',
  238.     'F',
  239.     'G',
  240.     'H',
  241.     'I',
  242.     'J',
  243.     'K',
  244.     'L',
  245.     'M',
  246.     'N',
  247.     'O',
  248.     'P',
  249.     'Q',
  250.     'R',
  251.     'S',
  252.     'T',
  253.     'U',
  254.     'V',
  255.     'W',
  256.     'X',
  257.     'Y',
  258.     'Z',
  259.     '[',
  260.     ']',
  261.     '{',
  262.     '}',
  263.     };
  264.  
  265. //----------------------------------------------------------------------------
  266. //   Description:    Decode a buffer
  267. //    Parameters:    pbDecode            Pointer to buffer to decode.
  268. //                        pcDecode            Pointer to recieve number of bytes decoded.
  269. //                        pch                Buffer to place decoded text into.
  270. //                                            Null terminator is added to buffer.
  271. //       Returns:    TRUE if successful.
  272. //----------------------------------------------------------------------------
  273. BOOL FN_E AsciiDecode(PBYTE pbDecode, PSIZET pcDecode, PCHAR pch)
  274. {
  275.     SIZET cDecode = 0;
  276.     SIZET cBitsLeft = 0;
  277.     BYTE bVal, bBits, bInput;
  278.  
  279.     Assert(pbDecode && pcDecode && pch);
  280.     for (;;)
  281.         {
  282.         if (cBitsLeft < 6)
  283.             {
  284.             bInput = *pbDecode++;
  285.             cDecode++;
  286.             }
  287.         switch (cBitsLeft)
  288.             {
  289.             case 0:
  290.                 bVal = (BYTE)(bInput >> 2);
  291.                 bBits = bInput;
  292.                 cBitsLeft = 2;
  293.                 break;
  294.  
  295.             case 2:
  296.                 bVal = (BYTE)((bBits << 4) | (bInput >> 4));
  297.                 bBits = bInput;
  298.                 cBitsLeft = 4;
  299.                 break;
  300.  
  301.             case 4:
  302.                 bVal = (BYTE)((bBits << 2) | (bInput >> 6));
  303.                 bBits = bInput;
  304.                 cBitsLeft = 6;
  305.                 break;
  306.  
  307.             case 6:
  308.                 bVal = bBits;
  309.                 cBitsLeft = 0;
  310.                 break;
  311.             }                                        // Decode it
  312.         *pch = (CHAR)bEncoded2Ascii[bVal & 0x3F];
  313.         if (*pch == '\0')                        // Decoded end of line?
  314.             break;
  315.         pch++;                                    // Move to next character
  316.         }
  317.     *pcDecode = cDecode;
  318.     return TRUE;
  319. }
  320.  
  321.  
  322. //----------------------------------------------------------------------------
  323. //   Description:    Encode a buffer
  324. //    Parameters:    pbEncode            Pointer to buffer to encode into.
  325. //                        pcEncode            Pointer to receive size of encoded text.
  326. //                        psz                Buffer to read text from.
  327. //       Returns:    TRUE if successful.
  328. //----------------------------------------------------------------------------
  329. BOOL FN_E AsciiEncode(PBYTE pbEncode, PSIZET pcEncode, PCSZ pcsz)
  330. {
  331.     SIZET cEncode = 0;
  332.     SIZET cBitsLeft = 8;
  333.     BYTE bBits = 0;
  334.     BYTE bVal, bOutput;
  335.  
  336.     Assert(pbEncode && pcEncode && pcsz);
  337.     for (;;)
  338.         {
  339.         if ((BYTE)pcsz[0] >= 128)
  340.             bVal = 255;
  341.         else
  342.             bVal = bAscii2Encoded[(BYTE)pcsz[0]];
  343.  
  344.         if (bVal != 255)
  345.             {
  346.             switch (cBitsLeft)
  347.                 {
  348.                 case 2:
  349.                     bOutput = (bBits | (bVal >> 4));
  350.                     bBits = (BYTE)(bVal << 4);
  351.                     cBitsLeft = 4;
  352.                     break;
  353.  
  354.                 case 4:
  355.                     bOutput = (bBits | (bVal >> 2));
  356.                     bBits = (BYTE)(bVal << 6);
  357.                     cBitsLeft = 6;
  358.                     break;
  359.  
  360.                 case 6:
  361.                     bOutput = (bBits | bVal);
  362.                     bBits = 0;
  363.                     cBitsLeft = 8;
  364.                     break;
  365.  
  366.                 case 8:
  367.                     bBits = (BYTE)(bVal << 2);
  368.                     cBitsLeft = 2;
  369.                     break;
  370.                 }
  371.             if (cBitsLeft != 2)
  372.                 {
  373.                 *pbEncode++ = bOutput;        // Output
  374.                 cEncode++;
  375.                 }
  376.             }
  377.         if (!pcsz[0])                            // End of string?
  378.             break;                                // Yes, done!
  379.         pcsz++;                                    // Move to next character
  380.         }
  381.     if (cBitsLeft != 8)                        // Stuff left over bits into buffer
  382.         {
  383.         *pbEncode = bBits;                    // Place into buffer
  384.         cEncode++;
  385.         }                                            // Return number of bytes used
  386.     *pcEncode = cEncode;
  387.     return TRUE;
  388. }
  389.  
  390.  
  391. //----------------------------------------------------------------------------
  392. //   Description:    Run standard test suite
  393. //    Parameters:    sTest        Test to run.
  394. //                                        0        Run all default tests (except).
  395. //       Returns:    TRUE if successful.
  396. //----------------------------------------------------------------------------
  397. #if COMPILE_TEST
  398. BOOL FN AsciiTest(SHORT sTest)
  399. {
  400. static BYTE bBuf[512];
  401. static SIZET cBuf;
  402. static CHAR szInput[512];
  403. static CHAR szResult[512];
  404.     SIZET i;
  405.  
  406.     if (sTest == 0 || sTest == 1)
  407.         {
  408. static PSZ pszTest1 = "abc";
  409.  
  410.         if (!AsciiEncode(bBuf, &cBuf, pszTest1))
  411.             return FALSE;
  412.  
  413.         if (cBuf != (((strlen(pszTest1) + 1) * 6) + 6) / 8)
  414.             return FALSE;
  415.  
  416.         if (!AsciiDecode(bBuf, &cBuf, szResult))
  417.             return FALSE;
  418.  
  419.         if (stricmp(szResult, pszTest1) != 0)
  420.             return FALSE;
  421.         }
  422.     if (sTest == 0 || sTest == 2)
  423.         {
  424.         memset(szInput, 0, sizeof(szInput));
  425.  
  426.         for (i = 1; i < 256; ++i)
  427.             szInput[i - 1] = (CHAR)i;
  428.  
  429.         if (!AsciiEncode(bBuf, &cBuf, szInput))
  430.             return FALSE;
  431.  
  432.         if (!AsciiDecode(bBuf, &cBuf, szResult))
  433.             return FALSE;
  434.  
  435.         if (strlen(szResult) != 63 + 26)
  436.             return FALSE;
  437.         }
  438.     return TRUE;
  439. }
  440. #endif
  441. //----------------------------------------------------------------------------
  442. //------------------------------- End of File --------------------------------
  443. //----------------------------------------------------------------------------
  444.  
  445.